package com.gradumate.client.gui;

import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.gradumate.client.Element;
import com.gradumate.client.GraduMate;
import com.gradumate.client.service.GraduMateService;
import com.gradumate.client.service.GraduMateServiceAsync;
import com.gradumate.shared.ContentItem;
import com.gradumate.shared.Gebruiker;
import com.gradumate.shared.LoginToken;

/**
 * 
 * @author Hugo Zonderland
 * 
 *         Op deze pagina kunnen leden van de afstudeercommissie de beoordeling
 *         invullen van een afstudeervoorstel. Wanneer het voorstel word
 *         goedgekeurd ontvangt de student een mailtje waarin staat dat hij met
 *         zijn afstudeer opdracht mag gaan beginnen. Bij afkeuring word er om
 *         een motivatie gevraagd.
 * 
 *         Beiden resultaten worden verwerkt in Alfresco. De student krijgt in
 *         beiden gevallen een email met daarin de beoordeling, bij afkeuring
 *         staat de reden van afkeuren erbij vermeld.
 * 
 */
public class AfstudeercommissieAfstudeerVoorstelDetail {

	// Asyncserver
	private GraduMateServiceAsync server = GWT.create(GraduMateService.class);

	// Logger
	private final Logger log = Logger.getLogger(AfstudeercommissieAfstudeerVoorstelDetail.class.getName());

	// Element
	private Element element = new Element();

	// Table
	private FlexTable studentTable, voorstelTable;
	private int row;
	
	// Listbox
	private ListBox lstBeoordelingVoorstel;
	
	// Textbox
	private TextBox txtBeoordeling;
	
	// Label
	private Label lblBeoordeling;
	
	// Geselecteerde optie als String
	private String selectedOpt;
	
	// Submit button
	private Button btnSubmit;

	/**
	 * Constructor.
	 * 
	 * @param Gebruiker
	 *            student, de student waar de beoordeling voor word ingevuld.
	 */
	public AfstudeercommissieAfstudeerVoorstelDetail(Gebruiker student, LoginToken loginToken) {
		// Loading-gif plaatsen.
		GraduMate.setLoadingImage(true);
		GraduMate.clearStatusMessages();

		// TODO: Inladen van het afstudeervoorstel vanaf de server
		ContentItem afstudeervoorstel = new ContentItem();
		afstudeervoorstel.setTitle("Afstudeervoorstel " + student.getVoornaam() + " " + student.getAchternaam());
		afstudeervoorstel.setContent("Dit is de inhoud van het afstudeervoorstel");

		this.createForm(afstudeervoorstel, student, loginToken);
	}

	/**
	 * Functie die alle ingekomen data verwerkt en deze op het scherm plaatst.
	 * 
	 * @param ContentItem
	 *            afstudeervoorstel van de student.
	 * @param Gebruiker
	 *            student student die het voorstel heeft ingediend.
	 */
	private void createForm(ContentItem afstudeervoorstel, final Gebruiker student, final LoginToken loginToken) {
		// Flextable opnieuw aanmaken
		FlexTable hTable = new FlexTable();
		hTable.setStyleName("datatableNoBorder");

		// Header op het panel plaatsen.
		hTable.setWidget(0, 0, element.getHeaderLabel("Afstudeervoorstel van " + student.getVoornaam() + " " + student.getAchternaam()));

		// Table aanmaken
		studentTable = new FlexTable();
		studentTable.setStyleName("datatable");
		studentTable.setCellSpacing(0);
		studentTable.setCellPadding(0);
		row = 0;
		
		// Informatie over de student
		studentTable.setWidget(row, 0, element.getH2Label("Student informatie"));
		row++;
		
		// Voor- achternaam van de student
		studentTable.setWidget(row, 0, element.getLabel("Naam student"));
		studentTable.setWidget(row, 1, element.getLabel(student.getVoornaam() + " " + student.getAchternaam()));
		row++;
		
		// Studentnummer
		studentTable.setWidget(row, 0, element.getLabel("Studentnummer"));
		studentTable.setWidget(row, 1, element.getLabel("" + student.getStudentNummer()));
		row++;
		
		// Student email
		studentTable.setWidget(row, 0, element.getLabel("Student email"));
		studentTable.setWidget(row, 1, element.getLabel(student.getGebruikerEmail()));
		row++;
		
		// Opleidings informatie
		studentTable.setWidget(row, 0, element.getLabel("Faculteit"));
		studentTable.setWidget(row, 1, element.getLabel(student.getFaculteit()));
		row++;
		
		studentTable.setWidget(row, 0, element.getLabel("Instituut"));
		studentTable.setWidget(row, 1, element.getLabel(student.getInstituut()));
		row++;
		
		studentTable.setWidget(row, 0, element.getLabel("Opleiding"));
		studentTable.setWidget(row, 1, element.getLabel(student.getOpleiding().get(0)));
		
		// Table aanmaken
		voorstelTable = new FlexTable();
		voorstelTable.setStyleName("datatable");
		voorstelTable.setCellSpacing(0);
		voorstelTable.setCellPadding(0);
		row = 0;
		
		// Informatie over de student
		voorstelTable.setWidget(row, 0, element.getH2Label("Voorstel informatie"));
		row++;
		
		// Document ter download aanbieden.
		Button btnDocumentInzien = element.getButton(afstudeervoorstel.getTitle(), afstudeervoorstel.getTitle(), "page_word.png");
		btnDocumentInzien.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent e) {
				server.openDocument(student, new AsyncCallback<String>() {
					public void onFailure(Throwable caught) {
						log.info("het tonen van het document is mislukt");
						
					}
					public void onSuccess(String result) {
						log.info("URL om het document te tonen: " + result);
						Window.open(result, "_blank", "");	
					}
				});
			}
		});
		voorstelTable.setWidget(row, 0, element.getLabel("Document inzien"));
		voorstelTable.setWidget(row, 1, btnDocumentInzien);
		row++;
		
		//Document downloaden
		Button btnDocumentDownloaden = element.getButton("Download Afstudeervoorstel", "Download Afstudeervoorstel", "arrow_down.png");
		btnDocumentDownloaden.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent e) {
				server.openDocument(student, new AsyncCallback<String>() {
					public void onFailure(Throwable caught) {
						log.info("het tonen van het document is mislukt");
						
					}
					public void onSuccess(String result) {
						String url = result + "&a=true";
					
						log.info("URL om het document te downloaden: " + result);
						Window.open(url, "_self", "");	
					}
				});
			}
		});
		voorstelTable.setWidget(row, 0, element.getLabel("Document downloaden"));
		voorstelTable.setWidget(row, 1, btnDocumentDownloaden);
		row++;
		
		// Beoordeling
		lstBeoordelingVoorstel = new ListBox();
		lstBeoordelingVoorstel.addItem("Kies een beoordeling", "");
		lstBeoordelingVoorstel.addItem("Goedkeuren", "true");
		lstBeoordelingVoorstel.addItem("Afkeuren", "false");
		lstBeoordelingVoorstel.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent e) {				
				selectedOpt = lstBeoordelingVoorstel.getValue(lstBeoordelingVoorstel.getSelectedIndex());
				// Wanneer goedgekeurd, true dan moeten de velden niet zichtbaar zijn.
				showBeoordeling(!selectedOpt.equals("true") && !selectedOpt.equals(""));
			}
		});
					
		voorstelTable.setWidget(row, 0, element.getLabel("Beoordeling voorstel"));
		voorstelTable.setWidget(row, 1, lstBeoordelingVoorstel);
		row++;
		
		// Textbox voor motivatie afkeuring
		txtBeoordeling = new TextBox();
		txtBeoordeling.setVisible(false);
		lblBeoordeling = element.getLabel("Beoordeling");
		lblBeoordeling.setVisible(false);
		voorstelTable.setWidget(row, 0, lblBeoordeling);
		voorstelTable.setWidget(row, 1, txtBeoordeling);
		row++;
		
		// Submit button + event.
		btnSubmit = element.getOpslaanButton();
		btnSubmit.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent e) {
				// Loading gif plaatsen
				setButtonLoadingImage(true);
				
				// true = goedgekeurd
				boolean beoordeling = lstBeoordelingVoorstel.getValue(lstBeoordelingVoorstel.getSelectedIndex()).equals("true");
				
				// Commentaar 
				String motivatie = "1";
				
				// Bepaald of het zaakje naar Alfresco gestuurd word
				boolean send = true;
				
				// Wanneer de beoordeling false is, negatief moet motivatie ingevuld zijn.
				if (!beoordeling) {
					motivatie = txtBeoordeling.getValue();
					if (motivatie != null && !(motivatie.length() > 0)) {
						// Loading gif uitzetten
						setButtonLoadingImage(false);
						
						// Foutmelding tonen
						GraduMate.addErrorMsg("Bij afkeuring is het motivatie veld verplicht.");
						send = false;
					} 
				}

				// Wanneer true mag er naar Alfresco gestuurt worden.
				if (send) {
					server.setAfstudeerVoorstelBeoordeling(student, GraduMate.getGebruiker(), beoordeling, motivatie, new AsyncCallback<Boolean>(){
						@Override
						public void onFailure(Throwable caught) {
							log.info("Service failure -> setAfstudeerVerzoekBeoordeling() -> " + caught.getMessage());
							GraduMate.addAsyncError();
							// Loading gif uitzetten
							setButtonLoadingImage(false);
						}
						@Override
						public void onSuccess(Boolean result) {
							// Loading gif verwijderen
							setButtonLoadingImage(false);
							
							if (result) {		
								// Beoordeling word geveild dan moet de Token ook worden verwijderd.
								if (loginToken != null) {
									server.deleteLoginToken(loginToken, new AsyncCallback<Boolean>() {
										public void onFailure(Throwable caught) {
											log.info("Service failure -> deleteLoginToken() -> " + caught.getMessage());
											GraduMate.addAsyncError();
										}
	
										@Override
										public void onSuccess(Boolean result) {
											log.info("Is de LoginToken verwijderd? " + result);
										}
									});
								}
								// Succes bericht op het scherm zetten.
								GraduMate.addSuccessMsg("De beoordeling is opgeslagen! Er is een mail gestuurd naar de student.");
								// Button uitzetten zodat de opdracht niet nog een keer kan worden verstuurd.
								btnSubmit.setEnabled(false);
							} else {
								GraduMate.addErrorMsg("Het opslaan is niet gelukt. Probeer het later nog een keer.");
							}
						}
					});
				}
			}
		});
		
		// Button table
		FlexTable flxButton = new FlexTable();
		flxButton.setStyleName("datatableNoBorder");
		flxButton.setCellSpacing(0);
		flxButton.setCellPadding(0);
		flxButton.setWidget(0, 0, btnSubmit);
		
		
		// Laadimage uit
		GraduMate.setLoadingImage(false);
		
		// Rootpanel schoonvegen en tabellen erop zetten
		RootPanel.get("main").clear();
		RootPanel.get("main").add(hTable);
		RootPanel.get("main").add(studentTable);
		RootPanel.get("main").add(voorstelTable);
		RootPanel.get("main").add(flxButton);
	}
	
	/**
	 * Verbergt de beoordeling elementen
	 * @param Boolean show geeft aan of de elementen zichtbaar moeten zijn of niet
	 */
	private void showBeoordeling(boolean show) {
		txtBeoordeling.setVisible(show);
		lblBeoordeling.setVisible(show);
	}
	
	/**
	 * Plaatje op de Save button plaatsen, leuke feature.
	 * @param show
	 */
	private void setButtonLoadingImage(boolean show) {
		if (show) {
			btnSubmit.setHTML("Laden.. " + element.getImage("Laden..", "ajax-loader.gif").toString());
		} else {
			btnSubmit.setHTML("Opslaan " + element.getImage("Opslaan", "disk.png").toString());
		}
	}
}
